//
//  TestService.swift
//  LeGou
//
//  Created by lxm on 2022/11/17.
//

import Foundation
class TestService {
    private init(){}
    static let shared = TestService()

    var loginDisposeBag = DisposeBag()
    
    var disposeBag = DisposeBag()

    var accountsArray = [
        ("18380446471", "a1111111"),
        ("18380446471", "a1111111"),
        ("18380446471", "a1111111")]
    
    var players = [TestPlayer]()
    
    var phoneArray = [String]()

    var registerStr = ""

    func login(onEnd: @escaping (()->())) {
        loginDisposeBag = DisposeBag()
        for ac in accountsArray {
            LoginAPI.psdLogin(["password" : ac.1, "phone" : ac.0]).rxRequest(type: TestLoginResponse.self).subscribe(onNext:{ r in
                TestAPI.userInfo([:], r.token, r.uid).rxRequest(type: CommonModels.UserInfo.self).subscribe(onNext:{ [unowned self] resp in
                    var temp = r
                    temp.showId = resp.showId
                    let p = TestPlayer(model: temp)
                    self.players.append(p)
                    onEnd()
                }, onError: { _ in
                    onEnd()
                }).disposed(by: self.loginDisposeBag)
            }, onError: { e in
                onEnd()
            }).disposed(by: loginDisposeBag)
        }
    }
    
    func autoRegister() {
        for p in phoneArray {
            LoginAPI.hadRegister(["phone" : p]).rxRequest(type: [String : Any].self).subscribe(onNext:{ [unowned self] resp in
                self.sendCode(phone: p)
            }).disposed(by: disposeBag)
        }
    }
    
    func sendCode(phone : String) {
        LoginAPI.sendCode(["phone" : phone]).rxRequestNullAble(type: Any.self).subscribe(onNext:{ [unowned self] resp in
            self.register(phone: phone)
        }).disposed(by: self.disposeBag)
    }
    
    func register(phone : String) {
        LoginAPI.loginOrRegister(["captcha" : "123456", "phone" : phone]).rxRequest(type: LoginModels.LoginResponse.self).subscribe(onNext:{ [unowned self] resp in
            self.fillInfo(phone: phone, token: resp.token, userId: resp.uid)
        }).disposed(by: disposeBag)
    }
    
    func fillInfo(phone : String, token : String, userId : Int) {
        TestAPI.setPsdAndCity(["password" : "a1111111", "cityId" : "592600"], token, userId).rxRequestNullAble(type: Any.self).subscribe(onNext:{ [unowned self] resp in
            self.inviteCodeSet(phone: phone, token: token, userId: userId)
        }).disposed(by: disposeBag)
    }
    
    func inviteCodeSet(phone : String, token : String, userId : Int) {
        var pa = [String : Any]()
        TestAPI.inviteCode(pa, token, userId).rxRequestNullAble(type: Any.self).subscribe(onNext:{ [unowned self] resp in
            self.registerStr.append("\(phone)@a1111111,")
            XMLogger.info("注册成功:" + self.registerStr)
        }).disposed(by: disposeBag)
    }
    
}

class TestPlayer {
    var disposeBag = DisposeBag()
    init(model : TestLoginResponse) {
        self.model = model
    }
    
    var playStatus = false
    
    var model : TestLoginResponse!
    
    var userId : Int {
        get {
            model.uid
        }
    }
    
    var token : String {
        get {
            model.token
        }
    }
    
    var showId : String {
        get {
            model.showId
        }
    }
    
    var onLog : ((_ log : String)->())?
    
    func playOnce() {
        if !playStatus {return}
        rollTheActivity(token: token, userId: userId) {
            self.playOnce()
        }
    }
    
    func rollTheActivity(token : String, userId : Int, onEnd : @escaping (()->())) {
        // 轮询活动
        let begin = Date()
        TestAPI.getActivities([:], token, userId).rxRequestNullAble(type: [AuctionModels.Acitivity].self).subscribe(onNext:{ [unowned self] resp in
            if let okAc = resp?.first(where: {$0.state == .process}) {
                getAcList(acId: okAc.id, token: token, userId: userId, onEnd: onEnd)
                self.logInfo("活动请求耗时：\(Date().timeIntervalSince1970 - begin.timeIntervalSince1970)S")
            } else {
                onEnd()
            }
        }, onError: { e in
            onEnd()
        }).disposed(by: disposeBag)
    }

    func getAcList(acId : Int, token : String, userId : Int, onEnd : @escaping (()->())) {
        let pa = ["activityId" : acId, "page" : 1, "size" : 10] as [String : Any]
        let begin = Date()
        
        testCallApi(api: TestAPI.getAuctionList(pa,token,userId), type: [AuctionModels.Goods].self, textStr: "列表请求").subscribe(onNext:{ [unowned self] resp in
            if let one = resp.first {
                self.getDetail(goodsId: one.id, token: token, userId: userId, onEnd: onEnd)
            } else {
                onEnd()
            }
        }, onError: { e in
            onEnd()
        }).disposed(by: disposeBag)
    }
    
    func getDetail(goodsId : Int, token : String, userId : Int, onEnd : @escaping (()->())) {
        testCallApi(api: TestAPI.auctionDetail(goodsId, token, userId), type: AuctionModels.AuctionDetail.self, textStr: "竞购详情接口").subscribe(onNext:{ [unowned self] resp in
            // 点击竞购
            if resp.state != .wait && resp.state != .success {
                self.auction(goodsId: goodsId, token: token, userId: userId, onEnd: onEnd)
            } else {
                onEnd()
            }
        }, onError: { e in
            onEnd()
        }).disposed(by: disposeBag)
    }
    
    func logInfo(_ info : String) {
        if let onLog = onLog {
            onLog(info)
        }
        XMLogger.info(info)
    }
    
    //竞购
    func auction(goodsId : Int, token : String, userId : Int, onEnd : @escaping (()->())) {
        let typeStr = "AUCTION"
        let id = "10"
        TestAPI.create_auth_code(["id" : id,"userId":userId, "type":typeStr], token, userId).rxRequest(type: String.self).flatMapLatest { r ->  Observable<[String : Any]> in
            // 生成本地将军令
            let code = AppHelper.generalOrder(userId: "\(userId)",
                                              randomKey: token,
                                              showId: self.showId,
                                              time: Int(r) ?? 0,
                                              type: typeStr, id: id)
            let pa = [
                "code" : code,
                "encryptedContent" : self.encryptParams(recordId : goodsId),
                "userId" : userId,
            ] as [String : Any]
            return self.testCallApi(api: TestAPI.autoAction(pa, token, userId), type: [String : Any].self, textStr: "落锤接口")
        }.subscribe(onNext:{ [unowned self] resp in
            ZMToast.hiddenActivity()
            let json = JSON(resp)
            // 成功
            if json["state"].int == 0 {
                // 成功
            } else if json["balanceState"].boolValue  {
                // 保证金不足, 弹框支付
            } else {
                // 失败
            }
            onEnd()
        }, onError: { e in
            onEnd()
        }).disposed(by: disposeBag)
    }
    
    func encryptParams(recordId : Int) -> String {
        let pa = "{recordId : \(recordId)}"
        let after = ZMOcHelper.encrypt(pa, key: theKey)
        return after
    }
    
    func testCallApi<T>(api : ZMApiProvider, type: T.Type, textStr : String) ->Observable<T> {
        let begin = Date()
        let obable = Observable<T>.create { (obser) -> Disposable in
            let dis = ZMAPIManage<T>.rxSendRequest(api).subscribe(onNext:{ resp in
                self.logInfo("\(textStr)\n请求耗时：\(String(format: "%.2f", Date().timeIntervalSince1970 - begin.timeIntervalSince1970))S")
                if resp.code == .success, let data = resp.data {
                    obser.onNext(data)
                    obser.onCompleted()
                }
                else {
                    let e = NSError(domain: resp.message, code: resp.code.rawValue)
                    obser.onError(e)
                }
            })
            return dis
        }
        return obable
    }
    
    
    
 
    
    
}


/// 登录响应模型
struct TestLoginResponse : HandyJSON {
    var nikeName = ""
    var phone = ""
    var token = ""
    var uid = 0
    var randomKey = ""
    var showId = ""
}



